-module(agent).
-behaviour(gen_server).

-export([start_link/1, stop/0, init/1, terminate/2, code_change/3, handle_cast/2, handle_info/2, handle_call/3]).

-include("common.hrl").

-record(state, {id = 0,pid=0,sid=0,ip=0}).
-define(SCENE_TIMER_INTERVAL,200).


start_link(Data) ->
    gen_server:start_link(?MODULE, Data, []).

stop() ->
    gen_server:cast(?MODULE, stop).


init(InitData) ->
	?debug("InitData=~p",[InitData]),
	{Sid,SceneIdList,Data}=InitData,
	?debug("Data=~p",[Data]), 
	try
		fun_login:login_check({Sid,Data,SceneIdList})
	catch E:R ->
			 ?log_error("E=~p,R=~p,error=~p",[E,R,erlang:get_stacktrace()])
	end,		 
	{ok, #state{sid=Sid}}.

    

terminate(_Reason, #state{id =Token_Id}) ->
	?debug("agent terminate,id=~p,name=~p",[Token_Id,get(name)]),
%% 	gen_server:cast({global, scene_mng},{scene_del,ID}),		
	ok.

code_change(_OldVsn, State, _Extra) ->    
    {ok, State}.


handle_call({apply, Module, Func, Args}, _From, State) ->
	Ret = 
	try
		erlang:apply(Module, Func, Args)
	catch
		E:R -> {call_failed, {E,R,erlang:get_stacktrace()}}
	end,
	{reply, Ret, State};
handle_call(_Request, _From, State) ->    
    {reply, ok, State}.

handle_info({timeout, TimerRef, {xtimer_callback, CallBackInfo}}, State) ->
	try
		xtimer:on_timer(TimerRef, CallBackInfo)
	catch E:R ->?log_error("timeout error,data=~p,E=~p,R=~p,stack=~p",[CallBackInfo,E,R,erlang:get_stacktrace()])
	end,
	{noreply, State};

		
handle_info(Request, State) ->
	?log_warning("info,info=~p",[Request]),
    {noreply, State}.
handle_cast({tcp_closed,Uid},  State) ->
	ets:delete(logic_agent,Uid),
	gen_server:cast(self(), stop),
	 {noreply, State};
handle_cast({recv, Sid, Uid, Recv},  State) ->
	Tsid=get(sid),
	Tuid=get(uid),
	if
        Sid == Tsid, Uid == Tuid ->			    		 
		case Recv of
			<<Cmd:?u16, Data/binary>> ->
				doMsg(State, Data, Cmd);	
			_R-> ?debug("error Rev=~p",[_R]) 
		end,
		{noreply, State};
        true ->{noreply, State}
    end;   

handle_cast(stop, #state{} = State) ->
%% 	try 
%% 		fun_scene:on_close(Scene)
%% 	catch 
%% 		E:R -> ?log_error("scene on_close error E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()])
%% 	end,
    {stop, normal, State};

handle_cast({apply, Module, Func, Args}, State) ->
	try
		erlang:apply(Module, Func, Args)
	catch
		E:R -> ?log_error("apply error E=~p,R=~p,stack=~p", [E,R,erlang:get_stacktrace()])
	end,
	{noreply, State};

handle_cast(Msg, State) ->
	try 
		fun_agent:on_msg(Msg)
	catch 
		E:R -> ?log_error("scene handle_cast error E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()])
	end,		   
	{noreply, State}.


doMsg(State, Binary, Cmd) ->
	?debug("Binary=~p,Cmd=~p",[Binary,Cmd]).

						
